<template>
  <view :id="scrollId" class="mxp-horizontal-scroll" :class="[cusClass]" :style="[sizeStyle]">
    <scroll-view :scrollLeft="scrollLeft" :showScrollbar="false" :scrollX="true" class="scroll-view" :style="sizeStyle" @scroll="onScroll">
      <view :id="scrollContentId" style="display: flex; flex-flow: row nowrap">
        <slot></slot>
      </view>
    </scroll-view>
    <view
      v-if="indicator && scrollContentWidth > scrollWidth"
      class="indicator-box"
      :style="[indicatorStyle, { background: indicatorColor, width: indicatorWidth + 'px', height: indicatorHeight + 'px' }]"
    >
      <view class="indicator" :style="newIndicatorBarStyle"></view>
    </view>
  </view>
</template>

<script lang="ts" setup>
  import { type CSSProperties, type PropType, computed, getCurrentInstance, onMounted, ref } from 'vue';
  import { publicStyeProps } from '../mxp-tool/utils/public-props';
  import type { $AllColorStr, $SizeUnitStr } from '@/mxp-ui/mxp-tool/types/interface';
  import { getDomSize } from '../mxp-tool/utils/dom';
  import { getOnlyID } from '../mxp-tool/utils/common';
  import type { ScrollViewOnScrollEvent } from 'mxp-uni-types';
  const props = defineProps({
    /** 自定义宽度，单位rpx */
    width: { type: String as PropType<$SizeUnitStr>, default: undefined },
    /** 自定义高度，单位rpx */
    height: { type: String as PropType<$SizeUnitStr>, default: undefined },
    /** 是否显示指示器 */
    indicator: { type: Boolean, default: true },
    /** 指示器宽度，单位 px */
    indicatorWidth: { type: Number, default: 48 },
    /** 指示器高度，单位 px */
    indicatorHeight: { type: Number, default: 6 },
    /** 指示器里面的滑块宽度 */
    indicatorBarWidth: { type: Number, default: 24 },
    /** 自定义指示器样式 */
    indicatorStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 指示器颜色 */
    indicatorColor: { type: String as PropType<$AllColorStr>, default: '#d1d5f5' },
    /** 指示器滑块颜色 */
    indicatorBarColor: { type: String as PropType<$AllColorStr>, default: '#223aec' },
    ...publicStyeProps,
  });
  defineSlots<{
    /** 主体内容 */
    default?: () => void;
  }>();
  const emits = defineEmits<{
    (e: 'scroll', event: ScrollViewOnScrollEvent): void;
  }>();
  const scrollId = getOnlyID('mxp-horizontal-scroll');
  const scrollContentId = getOnlyID('mxp-horizontal-scroll-content');
  const instance = getCurrentInstance();
  const scrollWidth = ref(0);
  const scrollContentWidth = ref(0);
  onMounted(() => {
    setTimeout(() => {
      getDomSize(`#${scrollId}`, instance).then((res) => {
        scrollWidth.value = res.width || 0;
      });
      getDomSize(`#${scrollContentId}`, instance).then((res) => {
        scrollContentWidth.value = res.width || 0;
      });
    }, 100);
  });

  /** 滚动距离 */
  const scrollLeft = ref(0);

  /** 偏移量 */
  const translateX = ref(0);

  const sizeStyle = computed<CSSProperties>(() => {
    const style: CSSProperties = {};
    if (props.width) {
      style.width = props.width;
    }
    if (props.height) {
      style.height = props.height;
    }
    return style;
  });

  const newIndicatorBarStyle = computed<CSSProperties>(() => {
    return {
      background: props.indicatorBarColor,
      width: `${props.indicatorBarWidth}px`,
      height: `${props.indicatorHeight}px`,
      transform: `translateX(${translateX.value}px)`,
    };
  });

  /**
   * 滚动监听
   */
  function onScroll(event: ScrollViewOnScrollEvent) {
    emits('scroll', event);
    if (props.indicator) {
      const _scrollLeft = event.detail.scrollLeft;

      const maxTranslateWidth = props.indicatorWidth - props.indicatorBarWidth;
      let _translateX = (_scrollLeft * maxTranslateWidth) / (event.detail.scrollWidth - scrollWidth.value);
      if (_scrollLeft <= 0) {
        _translateX = 0;
      } else if (_translateX > maxTranslateWidth) {
        _translateX = maxTranslateWidth;
      }
      translateX.value = Math.round(_translateX);
    }
  }

  defineExpose({
    /** 滚动到指定位置 */
    scrollTo: (value: number) => {
      scrollLeft.value = value;
    },
  });
</script>

<style scoped lang="scss">
  .mxp-horizontal-scroll {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: 100%;

    .scroll-view {
      display: flex;
      flex-flow: row nowrap;
      width: 100%;
      height: auto;
      white-space: nowrap;
    }

    .indicator-box {
      margin-top: 10px;
      margin-right: auto;
      margin-left: auto;
      border-radius: 6px;

      .indicator {
        border-radius: 6px;
        transition: transform 0.06s linear;
        transform: translateX(0);
      }
    }
  }

  /* #ifndef APP-NVUE */
  .scroll-view::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
    color: transparent;
  }
  /* #endif */
</style>
